<template>
	<view class="aiStyle">
		<!-- 文字部分 -->
		<scroll-view class="talkStyle" v-for="(item, index) in historyTextList" :key="index">
			<view class="talk" v-if="item.role=='user'">
				<view class="textStyle">
					{{item.content}}
				</view>
				<view class="myText-left">
					<!-- <u-avatar :src="avatar"></u-avatar> -->
					<img style="width: 30px;" src="@/user.png" alt="" />
				</view>
			</view>



			<view class="talk_ai" v-if="item.role=='assistant'">
				<view class="myText-right">
					<img style="width: 30px;border-radius:50%;" src="@/fengmao.png" alt="" />
				</view>
				<view class="textStyle_ai">
					<view>{{item.content}}</view>
					<view class="icon_text">
						<view @click="resetSpark(index)">
							<view v-show="index!==0">
								<uni-icons custom-prefix="iconfont" type="icon-reset" size="16"
									style="margin-right: 8px;"></uni-icons>
								<span style="font-size: 12px;">重新回答</span>
							</view>
						</view>
						<view style="display: flex;">
							<!-- <uni-notice-bar style="width: 80px; height: 26px;margin-right: 5px;" scrollable single text="播放中播放中" v-show="!item.isBofang"></uni-notice-bar> -->
							<uni-icons  type="mic-filled" size="18"
								@click="bofang(item.content,index)" v-show="item.isBofang"></uni-icons>
								<view  v-show="item.isBofang"  style="margin-right: 8px;font-size: 12px;">播放</view>
								<uni-icons  type="micoff-filled" size="18"
								@click="zanting(index)" v-show="!item.isBofang"></uni-icons>
								<view v-show="!item.isBofang" style="margin-right: 8px;font-size: 12px;">暂停</view>
							<uni-icons custom-prefix="iconfont" type="icon-fuzhi" size="18" style="margin-right: 8px;"
								@click="copy(item.content)"></uni-icons>
							<uni-icons custom-prefix="iconfont" type="icon-xihuan1" size="18" style="margin-right: 8px;"
								v-show="!item.isLike" @click="negation(index)"></uni-icons>
							<uni-icons custom-prefix="iconfont" type="icon-aixin" size="18"
								style="margin-right: 8px;color: red;" v-show="item.isLike"
								@click="negation(index)"></uni-icons>
						</view>
					</view>
				</view>
			</view>

		</scroll-view>
		<view class="bg">
			<view class="bottomStyle">
				<view class="inputText">
					<!-- <input class="input_div" v-model="TEXT" type="textarea" placeholder="请输入您要提问的问题"  @confirm="sendToSpark()"> -->
					<textarea class="input_div_textarea" v-model="TEXT" placeholder="请输入您要提问的问题" />
				</view>
				<view
					style="margin-left: 1%;margin-right: 1%;align-items: center; width: 30%; height: 50%;  display: flex;">
					<button :custom-style="customStyle" class="logowz"
						style="color:white;background-color: #a4a4d5;font-size: 12px" :type="btnType"
						@click="sendToSpark()" :loading="loadShow" :disabled="disabled">{{sendText}}</button>
				</view>
			</view>

		</view>
	</view>
</template>

<script>
	import * as base64 from "base-64"
	import CryptoJS from '../../static/crypto-js/crypto-js.js'
	// import parser from '../../static/fast-xml-parser/src/parser'
	import {
		getSignature
	} from './ApiAuthAlgorithm.js';
	import * as utf8 from "utf8"
	export default {
		data() {
			return {
				isBofang: true,
				num: 0,
				islike: false,
				isWD: false,
				// api
				btnType: "success",
				sendText: "发送",
				loadShow: false,
				customStyle: {
					// marginTop: '20px' // 注意驼峰命名，并且值必须用引号包括，因为这是对象
				},

				listTop: [
					''
				],
				avatar: "",
				avatarAi: "",
				textMy: "我",
				userName: '',
				inputStyle: {
					backgroundColor: '#fff',
					margin: '0',
					width: "100%",

					color: "#000",
					paddingLeft: "5px",
					borderRadis: "50%",
				},
				placeholderStyle: {
					color: "#000"
				},
				height: 80,
				autoHeight: false,
				TEXT: '',
				APPID: '77044e93', // 控制台获取填写
				APISecret: 'MGRmMGU2Mjk4OGNjNmExYjQ1YmZlOWQ2',
				APIKey: '57486c2f8f3da2f9c503dc73302667a8',
				sparkResult: '57486c2f8f3da2f9c503dc73302667a8',
				fileIds: [],
				historyTextList: [], // 历史会话信息，由于最大token12000,可以结合实际使用，进行移出
				tempRes: '', // 临时答复保存
				domain: "general", //模型
				temperature: 1, //核采样阈值。用于决定结果随机性，取值越高随机性越强即相同的问题得到的不同答案的可能性越高 取值为[0,1],默认为0.5
				max_tokens: 4096, //模型回答的tokens的最大长度 //V2.0取值为[1,8192]，默认为2048。//V3.0取值为[1,8192]，默认为2048。
				version: "v1.1", //版本
				talk: "",
				talkAi: "",
				talkList: [],
				disabled: false,
				count: 0,
				audioContext: undefined
			}
		},
		updated() {
			if (this.isWD) {
				uni.pageScrollTo({
					scrollTop: 100000,
					duration: 300
				});
				this.isWD = false
			}
		},
		onLoad(data) {
			this.userName = data.userName
			this.historyTextList.push({
				"role": "assistant",
				"content": data.userName + "欢迎您来到丰茂知识库！您可以提出您想问的问题，丰茂知识库会替您一一解答！",
				"isLike": false,
				"isBofang":true,
			})
		},
		methods: {
			copy(text) {
				this.$copyText(text).then(
					res => {
						uni.showToast({
							title: '复制成功',
							icon: 'none'
						})
					}
				)

			},
			negation(index) {
				this.historyTextList[index].isLike = !this.historyTextList[index].isLike
			},
			async sendToSpark() {
				if (this.TEXT.trim() != "" && this.TEXT.trim() != null) {
					await uni.request({
						method: "GET",
						url: 'http://47.109.87.159:48080/admin-api/contract/starFire/getXHFileList', //仅为示例，并非真实接口地址。
						header: {
							'tenant-id': '1', //自定义请求头信息
							'Authorization': 'Bearer test1'
						},
						success: (res) => {
							this.fileIds = res.data.data
						},
					});
					this.isWD = true
					let myUrl = await this.getWebSocketUrl();
					this.loadShow = true;
					this.disabled = true;
					this.tempRes = "";
					this.sendText = "解答中";
					// this.sparkResult = "";
					let realThis = this;
					this.socketTask = uni.connectSocket({
						url: myUrl,
						method: 'GET',
						success: res => {
							console.log(res, "ws成功连接...", myUrl)
							realThis.wsLiveFlag = true;
						}
					})
					realThis.socketTask.onError((res) => {
						console.log("连接发生错误，请检查appid是否填写", res)
					})
					realThis.socketTask.onOpen((res) => {
						this.isWD = true
						this.historyTextList.push({
							"role": "user",
							"content": this.TEXT,
						})
						console.info("wss的onOpen成功执行...", res)
						let params = {
							"chatExtends": {
								"wikiPromptTpl": "<wikicontent>\\n文档中没有的内容请自行搜索其他答案。\\n问题:<wikiquestion>",
								"wikiFilterScore": 0.8,
								"sparkWhenWithoutEmbedding": true,
								"temperature": 0.5
							},
							"fileIds": this.fileIds,
							"messages": this.historyTextList
						}
						this.loadShow = true;
						this.sparkResult = this.sparkResult;
						realThis.socketTask.send({ // 发送消息，，都用uni的官方版本
							data: JSON.stringify(params),
							success() {
								console.log('第一帧发送成功')
							}
						});
					});

					// 接受到消息时
					realThis.socketTask.onMessage((res) => {
						this.isWD = true
						let obj = JSON.parse(res.data)
						if (obj.content && this.num !== 0) {
							this.historyTextList[this.historyTextList.length - 1].content = this
								.historyTextList[this.historyTextList.length - 1].content + obj.content
						}
						if (obj.content && this.num === 0) {
							this.historyTextList.push({
								"role": "assistant",
								"content": obj.content,
								"isLike": false,
								"isBofang":true,
							})
							this.num++
						}
						let temp = JSON.parse(res.data)
						if (temp.code !== 0) {
							console.log(`${temp.code}`);
							realThis.socketTask.close({
								success(res) {
									console.log('关闭成功', res)
									realThis.wsLiveFlag = false;
								},
								fail(err) {
									console.log('关闭失败', err)
								}
							})
						}
						if (temp.code === 0) {
							if (res.data && temp.status === 2) {
								this.num = 0;
								let _this = this;
								this.loadShow = false;
								this.TEXT = "";
								this.disabled = false;
								this.sendText = "发送";
								// this.historyTextList[this.historyTextList.length-1].isBofang = !this.historyTextList[this.historyTextList.length-1].isBofang
								// this.bofang(this.historyTextList[this.historyTextList.length-1].content,this.historyTextList.length-1)
								realThis.sparkResult = realThis.sparkResult
								console.log("结束")
								setTimeout(() => {
									realThis.socketTask.close({
										success(res) {
											console.log('关闭成功', res)
										},
										fail(err) {
											// console.log('关闭失败', err)
										}
									})
								}, 1000)
							}
						}
					})

				}
			},
			// 鉴权
			getWebSocketUrl() {
				return new Promise((resolve, reject) => {
					var url = "wss://chatdoc.xfyun.cn/openapi/chat";
					var date = Math.floor(new Date().getTime() / 1000);
					var signature = getSignature(this.APPID, this.APISecret, date);
					url = `${url}?appId=${this.APPID}&timestamp=${date}&signature=${signature}`;

					resolve(url); // 主要是返回地址
				});
			},
			//重新回答
			resetSpark(index) {
				if (this.sendText !== '发送') {
					return
				}
				this.TEXT = this.historyTextList[index - 1].content
				this.sendToSpark()
			},
			//播放
			bofang(content,index) {			
				if(this.audioContext){
					this.audioContext.stop(); //停止播放
				}
				console.log(content)
				this.historyTextList.forEach(item=>{
					if(!item.isBofang){
						item.isBofang = true
					}
				})
				
				this.historyTextList[index].isBofang = !this.historyTextList[index].isBofang
				uni.request({
					url: 'http://47.109.87.159:48080/admin-api/aliyun/speechFileDownload?context=' + content,
					method: 'GET',
					success: (res) => {
						// 将接收到的二进制数据保存为临时文件
						console.log(res.data)
						this.audioContext = uni.createInnerAudioContext();
						this.audioContext.src = res.data;
						// this.audioContext.loop = true //循环播放
						this.audioContext.play();
					},
					fail: (error) => {
						console.error('请求音频文件失败:', error);
					},
				});
				
			},
			//暂停
			zanting(index) {
				// this.isBofang = true
				this.historyTextList[index].isBofang = !this.historyTextList[index].isBofang
				this.audioContext.stop(); //停止播放
			}
		}
	}
</script>

<style>
	@import "@/static/iconfont.css";

	page {
		-webkit-user-select: text;
	}

	.aiStyle {
		display: flex;
		flex-direction: column;
		padding-bottom: 15%;
	}

	.bg {
		position: fixed;
		width: 100%;
		/* height: 100%; */
		bottom: 0;
		left: 0;
		z-index: 999;

	}

	page {
		position: relative;
		background-image: url("https://bpic.588ku.com/back_our/20201217/bg/89f905f39bc07.png");
		height: 100%;
		width: 100%;
		/* 背景图垂直、水平均居中 */
		background-position: center center;
		/* 背景图不平铺 */
		background-repeat: no-repeat;
		/* 当内容高度大于图片高度时，背景图像的位置相对于viewport固定 */
		background-attachment: fixed;
		/* 让背景图基于容器大小伸缩 */
		background-size: cover;
	}

	.bottomStyle {
		background: #f1f1f1;
		display: flex;
		align-items: center;
		justify-content: space-between;
		/* justify-content: space-around; */
		height: 70px;
	}

	.logowz {

		/* 	width: 100%;
		margin: 0 4% 0 0; */
	}

	.inputText {
		width: 66%;
		margin-left: 4%;
		background-color: white;
		height: 50%;
		display: flex;
		align-items: center;
		border-radius: 5%;
		padding-left: 15px;
	}

	.uni-input-input {
		width: 100%;
		height: 100%;
	}

	.myText-left {
		margin-left: 3%;

	}

	.myText-right {
		margin-right: 3%;

	}

	.talk {
		display: flex;
		align-items: center;
		margin: 5%;
		width: 90%;
		margin-left: 5%;
		justify-content: flex-end;
	}

	.talk_ai {
		display: flex;
		align-items: center;
		margin: 5%;
		width: 90%;
		margin-left: 5%;
		justify-content: start;
	}

	.talkStyle {
		height: 90%;
		width: 100%;
	}

	.textStyle {
		flex-wrap: wrap;
		ext-align: inherit;
		/* background: #fff;
		color: #000; */
		background: #1E90FF;
		color: #fff;
		padding: 10px;
		border-radius: 5px;
		word-wrap: break-word;
		/* 允许单词内断行 */
		white-space: normal;
		/* 处理空白符，自动换行 */
		line-height: 25px;
	}

	.textStyle_ai {
		word-wrap: break-word;
		/* 允许单词内断行 */
		white-space: normal;
		/* 处理空白符，自动换行 */
		flex-wrap: wrap;
		text-align: start;
		background: #fff;
		color: #000;
		/* background: #6ccb7c;
		color: #fff; */
		padding: 10px;
		padding-bottom: 0;
		border-radius: 5px;
		white-space: pre-line;
		line-height: 25px;
	}

	.icon_text {
		margin-top: 10px;
		margin-bottom: 5px;
		display: flex;
		justify-content: space-between;
	}

	.uni-actionsheet__cell ::v-deep {
		color: #6ccb7c;
	}

	.input_div_textarea {
		height: 20px;
	}
</style>